using System;
using System.Collections.Generic;
using BlobNet.Base.Collections;
using BlobNet.Base.Collections.List;
using BlobNet.Base.DataProviders;
using BlobNet.Base.Enums;
using BlobNet.TestsCommon.DataProviderHelpers.Base;
using BlobNet.TestsCommon.UnitTests.Dummy;
using NUnit.Framework;
using Rhino.Mocks;
using Rhino.Mocks.Impl;

namespace BlobNet.DefaultDataProviders.Tests.Base
{
    public abstract class KVSDataProviderTests
    {
        protected abstract DataProviderTestHelper Helper { get; }
        protected abstract IDataProvider NewDataProvider();

        #region Setup/Teardown

        [TearDown]
        public void AfterEachTest()
        {
            Helper.ClearTable(_predefinedBlobDomainId, TableEntities);
            Helper.ClearTable(_predefinedBlobDomainId, TableListEntities);
        }

        #endregion

        private const string TableEntities = "BlobStatusTable";
        private const string TableListEntities = "BlobPartsListTable";
        private readonly Guid _predefinedBlobDomainId = Guid.NewGuid();

        [TestFixtureSetUp]
        public void StartFixture()
        {
            RhinoMocks.Logger = new TextWriterExpectationLogger(Console.Out);
            //TODO: i know that works but modify test helper to create the full database before delivering
            NewDataProvider().CreateSchema(_predefinedBlobDomainId);
        }

        [TestFixtureTearDown]
        public void FixtureTearDown()
        {
            NewDataProvider().RemoveSchema(_predefinedBlobDomainId);
        }

        [Test]
        [Ignore("TODO")]
        public void Can_HasPropertyValue_Test()
        {
            
        }

        [Test]
        [Ignore("TODO")]
        public void Can_RetrieveRegisteredProperties_Test()
        {

        }
        
        [Test]
        public void AddEntityToCollection_Updates_Above_Positions_In_List_Test()
        {
            IDataProvider target = NewDataProvider();
            Guid collectionId = Guid.NewGuid();
            Guid entityId = Guid.NewGuid();
            Guid entityId2 = Guid.NewGuid();
            int position = 1;
            string typeSample = "This.Is.A.Test";

            target.AddEntityToCollection(_predefinedBlobDomainId, collectionId, position, typeSample, entityId);
            target.AddEntityToCollection(_predefinedBlobDomainId, collectionId, position, typeSample, entityId2);

            Dictionary<string, object> row = Helper.GetListEntitiesRow(_predefinedBlobDomainId,
                                                                                            collectionId, position);

            Assert.AreEqual(entityId2, row["Value"]);

            row = Helper.GetListEntitiesRow(_predefinedBlobDomainId, collectionId, position + 1);

            Assert.AreEqual(entityId, row["Value"]);
        }

        [Test]
        public void Can_AddArrayPropertyValue_Test() //this is not allowed but could be in the future
        {
            IDataProvider target = NewDataProvider();

            Guid ownerId = Guid.NewGuid();
            string propertyName = "TestProperty";
            PropertyValueType propertyValueType = PropertyValueType.Value;
            var expected = new[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
            string testType = "This.is.a.test";

            target.AddPropertyValue(_predefinedBlobDomainId, ownerId, propertyName, propertyValueType,testType, expected);

            Dictionary<string, object> row = Helper.GetEntitiesStatusRow(_predefinedBlobDomainId,
                                                                                              ownerId, propertyName);

            Assert.IsNotNull(row);
            Assert.IsTrue(row["Id"].ToString() == ownerId.ToString());
            Assert.IsTrue((string) row["PropertyName"] == propertyName);
            Assert.AreEqual(row["Value"], expected);
            Assert.AreEqual(row["FullyQualifiedType"], testType);
            Assert.IsTrue((PropertyValueType) Enum.Parse(typeof (PropertyValueType), (string) row["ValueType"]) ==
                          propertyValueType);
        }

        

        [Test]
        public void Can_AddNullEntityToCollection_Test()
        {
            IDataProvider target = NewDataProvider();
            Guid collectionId = Guid.NewGuid();

            int position = 1;
            string typeSample = "This.Is.A.Test";

            target.AddEntityToCollection(_predefinedBlobDomainId, collectionId, position, typeSample, null);

            Dictionary<string, object> row = Helper.GetListEntitiesRow(_predefinedBlobDomainId,
                                                                                            collectionId, position);

            Assert.IsNull(row["Value"]);
            Assert.IsTrue(row["FullyQualifiedType"].ToString() == typeSample);
        }

        [Test]
        public void Can_AddNullPropertyValue_Test()
        {
            IDataProvider target = NewDataProvider();

            Guid ownerId = Guid.NewGuid();
            string propertyName = "TestProperty";
            PropertyValueType propertyValueType = PropertyValueType.Value;
            object value = null;
            string testType = "This.is.a.test";
            target.AddPropertyValue(_predefinedBlobDomainId, ownerId, propertyName, propertyValueType,testType, value);

            Dictionary<string, object> row = Helper.GetEntitiesStatusRow(_predefinedBlobDomainId,
                                                                                              ownerId, propertyName);

            Assert.IsNotNull(row);
            Assert.IsTrue(row["Id"].ToString() == ownerId.ToString());
            Assert.IsTrue((string) row["PropertyName"] == propertyName);
            Assert.IsTrue(row["Value"] == null);
            Assert.IsTrue(row["FullyQualifiedType"].ToString() == testType);
            Assert.IsTrue((PropertyValueType) Enum.Parse(typeof (PropertyValueType), (string) row["ValueType"]) ==
                          propertyValueType);
        }

        [Test]
        public void Can_AddValueTypeToCollection_Test()
        {
            IDataProvider target = NewDataProvider();
            Guid collectionId = Guid.NewGuid();

            int position = 1;
            string typeSample = "This.Is.A.Test";

            int expected = 2;
            target.AddEntityToCollection(_predefinedBlobDomainId, collectionId, position, typeSample, expected);

            Dictionary<string, object> row = Helper.GetListEntitiesRow(_predefinedBlobDomainId,
                                                                                            collectionId, position);

            Assert.IsTrue((int) row["Value"] == expected);
            Assert.IsTrue(row["FullyQualifiedType"].ToString() == typeSample);
        }

     
        [Test]
        public void Can_Add_BlobPart_PropertyValue_Test()
        {
            IDataProvider target = NewDataProvider();

            Guid ownerId = Guid.NewGuid();
            string propertyName = "TestProperty";
            PropertyValueType propertyValueType = PropertyValueType.Value;
            Guid expected = Guid.NewGuid();
            string typeSample = "This.Is.a.Test";

            target.AddPropertyValue(_predefinedBlobDomainId, ownerId, propertyName, propertyValueType, typeSample, expected);

            Dictionary<string, object> row = Helper.GetEntitiesStatusRow(_predefinedBlobDomainId,
                                                                                              ownerId, propertyName);

            Assert.IsNotNull(row);
            Assert.IsTrue(row["Id"].ToString() == ownerId.ToString());
            Assert.IsTrue((string) row["PropertyName"] == propertyName);
            Assert.AreEqual(row["FullyQualifiedType"],typeSample);
            Assert.AreEqual(expected, row["Value"]);
            Assert.IsTrue((PropertyValueType) Enum.Parse(typeof (PropertyValueType), (string) row["ValueType"]) ==
                          propertyValueType);
        }

        [Test]
        public void Can_Add_BlobPart_ToCollection_Test()
        {
            IDataProvider target = NewDataProvider();
            Guid collectionId = Guid.NewGuid();
            Guid entityId = Guid.NewGuid();
            int position = 1;
            string typeSample = "This.Is.A.Test";

            target.AddEntityToCollection(_predefinedBlobDomainId, collectionId, position, typeSample, entityId);

            Dictionary<string, object> row = Helper.GetListEntitiesRow(_predefinedBlobDomainId,
                                                                                            collectionId, position);

            Assert.AreEqual(entityId, row["Value"]);
            Assert.IsTrue(row["FullyQualifiedType"].ToString() == typeSample);
        }

       

        [Test]
        public void Can_Add_ValueType_PropertyValue_Test()
        {
            IDataProvider target = NewDataProvider();

            Guid ownerId = Guid.NewGuid();
            string propertyName = "TestProperty";
            PropertyValueType propertyValueType = PropertyValueType.Value;
            var expected = new DateTime(1991, 11, 11);

            string testType = "This.is.a.test";
            target.AddPropertyValue(_predefinedBlobDomainId, ownerId, propertyName, propertyValueType,testType, expected);

            Dictionary<string, object> row = Helper.GetEntitiesStatusRow(_predefinedBlobDomainId,
                                                                                              ownerId, propertyName);

            Assert.IsNotNull(row);
            Assert.IsTrue(row["Id"].ToString() == ownerId.ToString());
            Assert.IsTrue((string) row["PropertyName"] == propertyName);
            Assert.AreEqual(expected, row["Value"]);
            Assert.IsTrue((PropertyValueType) Enum.Parse(typeof (PropertyValueType), (string) row["ValueType"]) ==
                          propertyValueType);
            Assert.AreEqual(row["FullyQualifiedType"].ToString(),testType);
        }


        [Test]
        public void Can_CopyRange_To_Destination_List()
        {
            Guid sourceId = Guid.NewGuid();

            string type = "This.is.A.Test";
            Helper.AddListEntitiesRow(_predefinedBlobDomainId, sourceId, type, 0, Guid.NewGuid());
            Helper.AddListEntitiesRow(_predefinedBlobDomainId, sourceId, type, 1, DateTime.Now);
            Helper.AddListEntitiesRow(_predefinedBlobDomainId, sourceId, type, 2, Guid.NewGuid());
            Helper.AddListEntitiesRow(_predefinedBlobDomainId, sourceId, type, 3, DateTime.Now);

            IDataProvider target = NewDataProvider();
            Guid destinationCollectionId = Guid.NewGuid();
            Assert.DoesNotThrow(
                () => target.CopyListRange(_predefinedBlobDomainId, sourceId, destinationCollectionId, 1, 2));

            Dictionary<string, object> original;
            Dictionary<string, object> copy;
            for (int i = 0; i < 2; i++)
            {
                original = Helper.GetListEntitiesRow(_predefinedBlobDomainId, sourceId, i + 1);
                copy = Helper.GetListEntitiesRow(_predefinedBlobDomainId, destinationCollectionId, i);

                Assert.AreEqual(copy["Value"], original["Value"]);
                Assert.AreEqual(copy["FullyQualifiedType"], original["FullyQualifiedType"]);
            }
        }

        [Test]
        public void Can_Get_Collection_Count_Test()
        {
            Guid collectionId = Guid.NewGuid();
            Guid entityId = Guid.NewGuid();
            int position = 1;
            string typeSample = "This.Is.A.Test";

            Helper.AddListEntitiesRow(_predefinedBlobDomainId, collectionId, typeSample,
                                                           position, entityId);
            IDataProvider target = NewDataProvider();

            int collectionCount = target.GetCollectionCount(_predefinedBlobDomainId, collectionId);

            Assert.IsTrue(collectionCount == 1);
        }

        [Test]
        [Ignore("need to be corrected")]
        public void Can_Retrieve_Items_Of_Type()
        {

            Guid ownerId1 = Guid.NewGuid();
            string propertyName1 = "TestProperty";
            PropertyValueType propertyValueType1 = PropertyValueType.Value;
            string value1 = "Sample value";
            string fullyQualifiedName1 = "type1";
            
            Helper.AddEntitiesStatusRow(_predefinedBlobDomainId, ownerId1, propertyName1,
                                                             ((int)propertyValueType1).ToString(), fullyQualifiedName1, value1);

            //has be a blobpart
            Guid ownerId2 = Guid.NewGuid();
            string propertyName2 = "TestProperty2";
            PropertyValueType propertyValueType2 = PropertyValueType.Value;
            var value2 = int.MaxValue;
            string fullyQualifiedName2 = value2.GetType().FullName;

            Helper.AddEntitiesStatusRow(_predefinedBlobDomainId, ownerId2, propertyName2,
                                                             ((int)propertyValueType2).ToString(), fullyQualifiedName2, value2);

            IDataProvider target = NewDataProvider();
            var actual = target.RetrieveItemsIds<int>(_predefinedBlobDomainId);

            Assert.IsNotNull(actual);
            Assert.IsTrue(actual.Count==1);
            Assert.AreEqual(actual[0],value2);

        }

        [Test]
        public void Can_Get_HasPropertyValueTrue()
        {
            IDataProvider target = NewDataProvider();

            Guid ownerId = Guid.NewGuid();
            string propertyName = "TestProperty";
            PropertyValueType propertyValueType = PropertyValueType.Value;
            string value = "Sample value";

            Helper.AddEntitiesStatusRow(_predefinedBlobDomainId, ownerId, propertyName,
                                                             ((int)propertyValueType).ToString(), "dummy",value);


            Assert.IsTrue(target.HasPropertyValue(_predefinedBlobDomainId, ownerId, propertyName));

        }

        [Test]
        public void Can_Get_HasPropertyValueFalse()
        {
            IDataProvider target = NewDataProvider();

            Guid ownerId = Guid.NewGuid();
            string propertyName = "TestProperty";

            Assert.IsFalse(target.HasPropertyValue(_predefinedBlobDomainId, ownerId, propertyName));


        }

        [Test]
        public void Can_Read_Original_Collection_Type_Test()
        {
            Assert.Inconclusive();
        }


        [Test]
        public void Can_RemoveEntity_Test()
        {
            IDataProvider target = NewDataProvider();

            Guid ownerId = Guid.NewGuid();
            string propertyName = "TestProperty";
            PropertyValueType propertyValueType = PropertyValueType.Value;
            string value = "Sample value";

            Helper.AddEntitiesStatusRow(_predefinedBlobDomainId, ownerId, propertyName,
                                                             ((int)propertyValueType).ToString(), "dummy", value);

            Assert.IsTrue(Helper.CountEntitiesStatusRows(_predefinedBlobDomainId, ownerId) == 1);

            target.RemovePropertyValues(_predefinedBlobDomainId, ownerId);

            Assert.IsTrue(Helper.CountEntitiesStatusRows(_predefinedBlobDomainId, ownerId) == 0);
        }

        [Test]
        public void Can_Remove_Collection_Test()
        {
            Guid collectionId = Guid.NewGuid();
            Guid entityId = Guid.NewGuid();
            int position = 1;
            string typeSample = "This.Is.A.Test";

            Helper.AddListEntitiesRow(_predefinedBlobDomainId, collectionId, typeSample,
                                                           position, entityId);
            IDataProvider target = NewDataProvider();

            target.RemoveCollection(_predefinedBlobDomainId, collectionId);

            Assert.IsTrue(
                Helper.GetListEntitiesRow(_predefinedBlobDomainId, collectionId, position).Count == 0);
        }

        [Test]
        public void Can_Remove_EntityFromCollection_Test()
        {
            Guid collectionId = Guid.NewGuid();
            Guid entityId = Guid.NewGuid();
            int position = 1;
            string typeSample = "This.Is.A.Test";

            Helper.AddListEntitiesRow(_predefinedBlobDomainId, collectionId, typeSample,
                                                           position, entityId);
            IDataProvider target = NewDataProvider();

            target.RemoveEntityFromCollection(_predefinedBlobDomainId, collectionId, position);

            Assert.IsTrue(
                Helper.GetListEntitiesRow(_predefinedBlobDomainId, collectionId, position).Count == 0);
        }

        [Test]
        public void Can_Remove_Original_Collection_Type_Test()
        {
            Assert.Inconclusive();
        }

        [Test]
        public void Can_RetrieveEntityIsReferenced()
        {
            IDataProvider target = NewDataProvider();

            Guid ownerId = Guid.NewGuid();
            string propertyName = "TestProperty";
            PropertyValueType propertyValueType = PropertyValueType.Entity;
            Guid usedReference = Guid.NewGuid();

            Assert.IsFalse(target.EntityIsReferenced(_predefinedBlobDomainId, usedReference));

            int position = 0;
            Helper.AddListEntitiesRow(_predefinedBlobDomainId, ownerId,
                                                           "Sample.Type", position, usedReference);

            Assert.IsTrue(target.EntityIsReferenced(_predefinedBlobDomainId, usedReference));

            Helper.RemoveListEntitiesRow(_predefinedBlobDomainId, ownerId, position);

            Helper.AddEntitiesStatusRow(_predefinedBlobDomainId, ownerId, propertyName,
                                                             ((int) propertyValueType).ToString(), "dummy",usedReference);

            Assert.IsTrue(target.EntityIsReferenced(_predefinedBlobDomainId, usedReference));
        }

        [Test]
        public void Can_RetrieveNullPropertyValue_Test()
        {
            IDataProvider target = NewDataProvider();

            Guid ownerId = Guid.NewGuid();
            string propertyName = "TestProperty";
            PropertyValueType propertyValueType = PropertyValueType.Value;
            string expected = null;

            Helper.AddEntitiesStatusRow(_predefinedBlobDomainId, ownerId, propertyName,
                                                             ((int) propertyValueType).ToString(),"dummy", expected);

            var actual = target.RetrievePropertyValue<string>(_predefinedBlobDomainId, ownerId, propertyName);

            Assert.IsTrue(expected == actual);
        }
        
        [Test]
        public void Can_RetrieveCollectionValue_Test()
        {
            IDataProvider target = NewDataProvider();

            Guid ownerId = Guid.NewGuid();
            string propertyName = "Test";
            PropertyValueType propertyValueType = PropertyValueType.Entity;
            var expected = new BlobList<DummyBlobPart>(){} ;

            Helper.AddEntitiesStatusRow(_predefinedBlobDomainId, ownerId, propertyName,
                                                             ((int)propertyValueType).ToString(),"dummy", expected);

            var actual = target.RetrievePropertyValue<BlobList<DummyBlobPart>>(_predefinedBlobDomainId, ownerId, propertyName);

            Assert.AreEqual(expected.Count, actual.Count);
            Assert.AreEqual(expected.EntityId, actual.EntityId);
        }
        

        [Test]
        public void Can_RetrievePropertyValue_Test()
        {
            IDataProvider target = NewDataProvider();

            Guid ownerId = Guid.NewGuid();
            string propertyName = "Rows";
            PropertyValueType propertyValueType = PropertyValueType.Value;
            string expected = "initial value";

            Helper.AddEntitiesStatusRow(_predefinedBlobDomainId, ownerId, propertyName,
                                                             ((int) propertyValueType).ToString(),"dummy", expected);

            var actual = target.RetrievePropertyValue<string>(_predefinedBlobDomainId, ownerId, propertyName);

            Assert.IsTrue(expected == actual);
        }

        [Test]
        public void Can_Retrieve_Collection_ItemByEntityId_Test()
        {
            Guid collectionId = Guid.NewGuid();
            Guid entityId1 = Guid.NewGuid();

            string typeSample = typeof (DummyBlobPart).ToString();

            Helper.AddListEntitiesRow(_predefinedBlobDomainId, collectionId, typeSample, 1, entityId1);

            IDataProvider target = NewDataProvider();

            ITupleList actual =
                target.RetrieveListItem(_predefinedBlobDomainId, collectionId, entityId1);

            Assert.AreEqual(entityId1, actual.Value);
            Assert.IsTrue(actual.ListId == collectionId);
            Assert.IsTrue(actual.Position == 1);
            Assert.IsTrue(actual.FullyQualifiedType == typeSample);
        }

        [Test]
        public void Can_Retrieve_Collection_Item_Test()
        {
            Guid collectionId = Guid.NewGuid();
            Guid entityId1 = Guid.NewGuid();

            string typeSample = typeof (DummyBlobPart).ToString();

            Helper.AddListEntitiesRow(_predefinedBlobDomainId, collectionId, typeSample, 1, entityId1);

            IDataProvider target = NewDataProvider();

            ITupleList actual =
                target.RetrieveListItem(_predefinedBlobDomainId, collectionId, 1);

            Assert.IsTrue(actual.ListId == collectionId);
            Assert.IsTrue(actual.Position == 1);
            Assert.IsTrue(actual.FullyQualifiedType == typeSample);
            Assert.AreEqual(entityId1, actual.Value);
        }

        [Test]
        public void Can_Retrieve_Collection_Items_Test()
        {
            Guid collectionId = Guid.NewGuid();
            Guid entityId1 = Guid.NewGuid();
            Guid entityId2 = Guid.NewGuid();

            string typeSample = typeof (DummyBlobPart).ToString();

            Helper.AddListEntitiesRow(_predefinedBlobDomainId, collectionId, typeSample, 1, entityId1);
            Helper.AddListEntitiesRow(_predefinedBlobDomainId, collectionId, typeSample, 2, entityId2);

            IDataProvider target = NewDataProvider();

            IList<ITupleList> actual =
                target.RetrieveListItems(_predefinedBlobDomainId, collectionId);

            Assert.IsTrue(actual.Count == 2);
            Assert.AreEqual(entityId1, actual[0].Value);
            Assert.AreEqual(entityId2, actual[1].Value);
            Assert.IsTrue(actual[0].ListId == collectionId);
            Assert.IsTrue(actual[1].ListId == collectionId);
            Assert.IsTrue(actual[0].Position == 1);
            Assert.IsTrue(actual[1].Position == 2);
            Assert.IsTrue(actual[0].FullyQualifiedType == typeSample);
            Assert.IsTrue(actual[1].FullyQualifiedType == typeSample);
        }


        [Test]
        public void Can_UpdateNullPropertyValue_Test()
        {
            IDataProvider target = NewDataProvider();

            Guid ownerId = Guid.NewGuid();
            string propertyName = "TestProperty";
            PropertyValueType propertyValueType = PropertyValueType.Value;
            string value = null;
            string testType = "testType";
            Helper.AddEntitiesStatusRow(_predefinedBlobDomainId, ownerId, propertyName,
                                                             ((int) propertyValueType).ToString(),"dummy", value);

            value = null;
            target.UpdatePropertyValue(_predefinedBlobDomainId, ownerId, propertyName, propertyValueType,testType, value);

            Dictionary<string, object> row = Helper.GetEntitiesStatusRow(_predefinedBlobDomainId,
                                                                                              ownerId, propertyName);

            Assert.IsNotNull(row);
            Assert.IsTrue(row["Id"].ToString() == ownerId.ToString());
            Assert.IsTrue((string) row["PropertyName"] == propertyName);
            Assert.AreEqual(row["Value"], value);
            Assert.AreEqual(row["FullyQualifiedType"].ToString(), testType);
            Assert.IsTrue((PropertyValueType) Enum.Parse(typeof (PropertyValueType), (string) row["ValueType"]) ==
                          propertyValueType);
        }

        [Test]
        public void Can_UpdatePropertyValue_Test()
        {
            IDataProvider target = NewDataProvider();

            Guid ownerId = Guid.NewGuid();
            string propertyName = "TestProperty";
            PropertyValueType propertyValueType = PropertyValueType.Value;
            string value = "initial value";
            string testType = "This.is.a.test";
            Helper.AddEntitiesStatusRow(_predefinedBlobDomainId, ownerId, propertyName,
                                                             ((int) propertyValueType).ToString(),"dummy", value);

            value = "Modified value";
            target.UpdatePropertyValue(_predefinedBlobDomainId, ownerId, propertyName, propertyValueType, testType, value);

            Dictionary<string, object> row = Helper.GetEntitiesStatusRow(_predefinedBlobDomainId,
                                                                                              ownerId, propertyName);

            Assert.IsNotNull(row);
            Assert.IsTrue(row["Id"].ToString() == ownerId.ToString());
            Assert.IsTrue((string) row["PropertyName"] == propertyName);
            Assert.IsTrue((string) row["Value"] == value);
            Assert.IsTrue((PropertyValueType) Enum.Parse(typeof (PropertyValueType), (string) row["ValueType"]) ==
                          propertyValueType);
            Assert.AreEqual(row["FullyQualifiedType"].ToString(), testType);
        }

        [Test]
        public void Can_Update_BlobPart_PropertyValue_Test()
        {
            IDataProvider target = NewDataProvider();

            Guid ownerId = Guid.NewGuid();
            string propertyName = "TestProperty";
            string testType = "This.is.a.test";
            PropertyValueType propertyValueType = PropertyValueType.Entity;
            Guid value = Guid.NewGuid();

            Helper.AddEntitiesStatusRow(_predefinedBlobDomainId, ownerId, propertyName,
                                                             ((int) propertyValueType).ToString(),"dummy", value);

            value = Guid.NewGuid();
            target.UpdatePropertyValue(_predefinedBlobDomainId, ownerId, propertyName, propertyValueType,testType, value);

            Dictionary<string, object> row = Helper.GetEntitiesStatusRow(_predefinedBlobDomainId,
                                                                                              ownerId, propertyName);

            Assert.IsNotNull(row);
            Assert.IsTrue(row["Id"].ToString() == ownerId.ToString());
            Assert.IsTrue((string) row["PropertyName"] == propertyName);
            Assert.AreEqual(row["Value"], value);
            Assert.IsTrue((PropertyValueType) Enum.Parse(typeof (PropertyValueType), (string) row["ValueType"]) ==
                          propertyValueType);
            Assert.AreEqual(row["FullyQualifiedType"].ToString(), testType);
        }

        [Test]
        public void Can_Update_BlobPart_ToCollection_Test()
        {
            IDataProvider target = NewDataProvider();
            Guid collectionId = Guid.NewGuid();
            Guid entityId = Guid.NewGuid();
            int position = 1;
            string typeSample = "This.Is.A.Test";

            Helper.AddListEntitiesRow(_predefinedBlobDomainId, collectionId, typeSample,
                                                           position, entityId);

            //Not the best assert!!
            Assert.IsTrue(
                Helper.GetListEntitiesRow(_predefinedBlobDomainId, collectionId, position).Count > 0);

            Dictionary<string, object> row = Helper.GetListEntitiesRow(_predefinedBlobDomainId,
                                                                                            collectionId, position);

            Assert.AreEqual(entityId, row["Value"]);
            Assert.IsTrue(row["FullyQualifiedType"].ToString() == typeSample);

            Guid entityId2 = Guid.NewGuid();
            typeSample = "Modified.Type";
            target.UpdateEntityToCollection(_predefinedBlobDomainId, collectionId, position, typeSample, entityId2);

            row = Helper.GetListEntitiesRow(_predefinedBlobDomainId, collectionId, position);

            Assert.AreEqual(entityId2, row["Value"]);
            Assert.IsTrue(row["FullyQualifiedType"].ToString() == typeSample);
        }

       

        [Test]
        public void Can_Update_ValueType_ToCollection_Test()
        {
            IDataProvider target = NewDataProvider();
            Guid collectionId = Guid.NewGuid();
            DateTime value = DateTime.Now;
            int position = 1;
            string typeSample = value.GetType().FullName;

            Helper.AddListEntitiesRow(_predefinedBlobDomainId, collectionId, typeSample,
                                                           position, value);

            //Not the best assert!!
            Assert.IsTrue(
                Helper.GetListEntitiesRow(_predefinedBlobDomainId, collectionId, position).Count > 0);


            DateTime value2 = DateTime.Now;
            typeSample = "Modified.Type";
            target.UpdateEntityToCollection(_predefinedBlobDomainId, collectionId, position, typeSample, value2);

            Dictionary<string, object> row = Helper.GetListEntitiesRow(_predefinedBlobDomainId, collectionId,
                                                                                            position);

            Assert.AreEqual(row["Value"], value2);
            Assert.IsTrue(row["FullyQualifiedType"].ToString() == typeSample);
        }

        [Test]
        public void CreateDataProviderTest()
        {
            IDataProvider target = NewDataProvider();
            Guid uniqueIdentifier = Guid.NewGuid();

            //try
            //{
            target.CreateSchema(uniqueIdentifier);

            //todo:Test that fields & indexes & SPs were created is not implemented
            Assert.IsTrue(Helper.TableExists(uniqueIdentifier, TableEntities));
            Assert.IsTrue(Helper.TableExists(uniqueIdentifier, TableListEntities));
            //}
            //catch (Exception ex)
            //{
            //    Assert.Fail(ex.Message);
            //}
            //finally
            //{
            NewDataProvider().RemoveSchema(uniqueIdentifier);
            //}
        }

        [Test]
        public void DefaultTest()
        {
            IDataProvider actual;
            actual = NewDataProvider();
            Assert.IsNotNull(actual);
        }

        [Test]
        public void FactoryCanCreateProvider()
        {
            //based in test config settings
            Assert.IsNotNull(DataProviderFactory.Provider);
        }

        [Test]
        public void Remove_EntityFromCollection_Updates_Above_Positions_Test()
        {
            Guid collectionId = Guid.NewGuid();
            Guid entityId = Guid.NewGuid();
            Guid entityId2 = Guid.NewGuid();
            int position = 1;
            string typeSample = "This.Is.A.Test";

            Helper.AddListEntitiesRow(_predefinedBlobDomainId, collectionId, typeSample,
                                                           position, entityId);
            Helper.AddListEntitiesRow(_predefinedBlobDomainId, collectionId, typeSample,
                                                           position + 1, entityId2);
            IDataProvider target = NewDataProvider();

            target.RemoveEntityFromCollection(_predefinedBlobDomainId, collectionId, position);

            Dictionary<string, object> row = Helper.GetListEntitiesRow(_predefinedBlobDomainId,
                                                                                            collectionId, position);

            Assert.AreEqual(entityId2, row["Value"]);
            Assert.IsTrue(Helper.CountListEntitiesRows(_predefinedBlobDomainId, collectionId) == 1);
        }
    }
}